<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="vjQCv" id="vjQCv"><span data-lake-id="u065e53a2" id="u065e53a2">典型回答</span></h1>
  <p data-lake-id="u1f43c97a" id="u1f43c97a"><br></p>
  <p data-lake-id="u20c0095d" id="u20c0095d"><span data-lake-id="u2e23cf42" id="u2e23cf42">想要实现一个分布式锁，一般需要考虑哪些问题？一般来说应该从以下几个方面来考虑：</span></p>
  <p data-lake-id="ud86d2d34" id="ud86d2d34"><span data-lake-id="udb7b7584" id="udb7b7584">​</span><br></p>
  <p data-lake-id="u6baf08be" id="u6baf08be"><span data-lake-id="ufa6b0917" id="ufa6b0917">​</span><br></p>
  <h3 data-lake-id="vNBrQ" id="vNBrQ"><span data-lake-id="ue545d742" id="ue545d742">互斥性</span></h3>
  <p data-lake-id="u0dcd0704" id="u0dcd0704"><br></p>
  <p data-lake-id="ud94ce1f1" id="ud94ce1f1"><span data-lake-id="u51af2dfd" id="u51af2dfd">一个分布式锁，最基本的要求，就是要具备互斥性，同一时间只能有一个线程获取到锁。否则就会出现并发问题。</span></p>
  <p data-lake-id="u0c5af983" id="u0c5af983"><span data-lake-id="u2ba47197" id="u2ba47197">​</span><br></p>
  <p data-lake-id="u10302b4b" id="u10302b4b"><span data-lake-id="u4ca59bab" id="u4ca59bab">在分布式场景中，想要实现一个分布式锁，必须要依赖一个第三方的分布式组件，比如数据库、Redis或者Zookeeper。借助自带的锁机制、单线程、互斥性等特点来实现互斥性。</span></p>
  <p data-lake-id="u988441ce" id="u988441ce"><span data-lake-id="uf1a01152" id="uf1a01152">​</span><br></p>
  <h3 data-lake-id="sEwuN" id="sEwuN"><span data-lake-id="u03922094" id="u03922094">避免死锁</span></h3>
  <p data-lake-id="uece05d8d" id="uece05d8d"><br></p>
  <p data-lake-id="u3ac17b4c" id="u3ac17b4c"><span data-lake-id="u26ce0034" id="u26ce0034">锁的死锁问题使我们不得不考虑的。尤其在在分布式环境中，由于网络延迟、节点故障等原因，会出现死锁的概率就会更高。所以我们在设计分布式锁的时候，一般都会设置一定的超时机制和死锁检测策略。</span></p>
  <p data-lake-id="u06006515" id="u06006515"><br></p>
  <h3 data-lake-id="UtDXW" id="UtDXW"><span data-lake-id="u6e03fee4" id="u6e03fee4">阻塞&amp;非阻塞</span></h3>
  <p data-lake-id="u0d7dbbc7" id="u0d7dbbc7"><br></p>
  <p data-lake-id="u5a55fd89" id="u5a55fd89"><span data-lake-id="u8e564bbc" id="u8e564bbc">根据加锁失败后是否阻塞持续自旋加锁，分布式锁可以分为阻塞锁和非阻塞锁。一般来说非阻塞锁用的比较多。像我们常用的Redis的分布式锁就是非阻塞锁。而使用数据库悲观锁 for update实现的可能就是个阻塞锁，</span></p>
  <p data-lake-id="ub3d4de49" id="ub3d4de49"><span data-lake-id="uf63205bc" id="uf63205bc">​</span><br></p>
  <p data-lake-id="u44717b52" id="u44717b52"><span data-lake-id="ucc6db924" id="ucc6db924">这个要根据业务的具体情况来做选择和设计</span></p>
  <p data-lake-id="u3281bb25" id="u3281bb25"><span data-lake-id="u9178bd07" id="u9178bd07">​</span><br></p>
  <h3 data-lake-id="gdUZI" id="gdUZI"><span data-lake-id="u9807ae26" id="u9807ae26">可重入</span></h3>
  <p data-lake-id="u6bae1d45" id="u6bae1d45"><br></p>
  <p data-lake-id="u1c60ebc0" id="u1c60ebc0"><span data-lake-id="ua6a956a4" id="ua6a956a4">一个线程，拿到锁之后，是否可以在未释放时重新获得锁。这就是可重入的特性了。可重入的锁不仅可以提升加锁效率，也能降低死锁的概率。</span></p>
  <p data-lake-id="u4aeda515" id="u4aeda515"><span data-lake-id="u1359df82" id="u1359df82">​</span><br></p>
  <p data-lake-id="u2d7dc8b1" id="u2d7dc8b1"><span data-lake-id="u7149972e" id="u7149972e">而且在有些业务场景中，对是否可以重入也会有一些要求。所以这个也是需要重点考量的。</span></p>
  <p data-lake-id="u36087aa0" id="u36087aa0"><span data-lake-id="u8fa424b6" id="u8fa424b6">​</span><br></p>
  <h3 data-lake-id="Xo30L" id="Xo30L"><span data-lake-id="u4730927f" id="u4730927f">锁的性能</span></h3>
  <p data-lake-id="u87cf2ffd" id="u87cf2ffd"><br></p>
  <p data-lake-id="u7f3a0e20" id="u7f3a0e20"><span data-lake-id="u817c3da2" id="u817c3da2">加锁性能是很重要的，尤其是分布式锁。因为在用分布式锁的场景一般并发较高，而如果分布式锁自身的性能差的话，对业务来说也是不可接受的。所以好的性能更重要。</span></p>
  <p data-lake-id="u06119218" id="u06119218"><span data-lake-id="uf2d347dc" id="uf2d347dc">​</span><br></p>
  <p data-lake-id="u6671a4fb" id="u6671a4fb"><span data-lake-id="u83042321" id="u83042321">​</span><br></p>
  <h3 data-lake-id="mjTNl" id="mjTNl"><span data-lake-id="u39977bfb" id="u39977bfb">可靠性</span></h3>
  <p data-lake-id="u382fb466" id="u382fb466"><br></p>
  <p data-lake-id="ub1c4b8a1" id="ub1c4b8a1"><span data-lake-id="u7459baf4" id="u7459baf4">一个分布式锁是否可靠，很重要，一旦他不可靠了，就可能会出现重复加锁导致并发问题。这也是为什么Redis的分布式锁从SetNX到Redisson再到RedLock的重要原因。</span></p>
  <p data-lake-id="ud98e615c" id="ud98e615c"><span data-lake-id="u8fc2d28d" id="u8fc2d28d">​</span><br></p>
  <h3 data-lake-id="gcskm" id="gcskm"><span data-lake-id="u743d1a20" id="u743d1a20">其他</span></h3>
  <p data-lake-id="u54e29d7d" id="u54e29d7d"><br></p>
  <p data-lake-id="u038b7628" id="u038b7628"><span data-lake-id="ubd6d6450" id="ubd6d6450">实现一个分布式锁，除了上面这些，还有一些其他的东西需要考虑，比如实现的复杂度、易用性等，都很重要的。</span></p>
  <p data-lake-id="u38fcda0a" id="u38fcda0a"><span data-lake-id="u458360f4" id="u458360f4">​</span><br></p>
  <p data-lake-id="u1d5c9557" id="u1d5c9557"><span data-lake-id="u7b2eeaaa" id="u7b2eeaaa">​</span><br></p>
 </body>
</html>